Dashboard 作為 Grafana 最重要的功能,它的建立與管理是絕對是重點關注之一。隨著 Dashboard 數量增加,手動維護大量 Dashboard 顯然不切實際,因此我們可以利用 Dashboard 匯入功能,甚至透過 API 批次處理。官方網站上社群提供的 Dashboard 也能讓我們快速建立基礎監控項目。
然而,有時匯入後的 Dashboard 可能無法正常顯示,原因可能是 Data Source 名稱不符,或服務的 Metrics 改版導致原有的 Query 失效。雖然可以手動 Debug 再用 Replace 大量取代,但管理大量 Dashboard 時,是否有更好的方法?這時,Dashboard as Code 就是解決方案,它能讓我們使用程式動態生成 Dashboard JSON。
Grafana 官方推薦使用 Jsonnet 作為 Dashboard as Code 的生成工具。這種解決方案最早由 Tom Wilkie 和 Frederic Branczyk 在 2018 年提出,當時他們開發了 Prometheus Monitoring Mixins 架構,並使用 Jsonnet 動態生成監控不同服務的 Grafana Dashboard、Prometheus 規則和告警設定。例如廣泛用於監控 Kubernetes 的 kube-prometheus-stack 使用的 Dashboard 就是來自 kubernetes-mixin。
Jsonnet 是 JSON 的擴展語言,支援自訂函數與變數,檔案副檔名為 libsonnet
。使用 Jsonnet 編譯 libsonnet
後,就可以動態生成 JSON 檔案,這樣就可以依據設定產生所需的 Dashboard。像是 Grafana Labs 的 Mimir 和 Loki,就附帶大量監控用的 Dashboard,例如 Mimir 的 mimir-mixin 和 Loki 的 loki-mixin,其內有許多 libsonnet
檔案,這些檔案就是使用 Jsonnet 編寫的 Dashboard,經編譯後可以生成 Dashboard JSON。
在 Jsonnet 的官網上提供了三種範例展示他的語法與編譯效果,包括基礎語法、自訂函數、搭配內建的 Manifestation 輸出成其他格式如 ini、conf 等格式,也可以直接編輯內容即時看到效果。
Jsonnet 官網的線上編輯器範例
如果想要在自己的機器上編譯 Jsonnet,需要安裝相應的編譯工具。Grafana 官方推薦使用 Go 實作的 go-jsonnet。此外,通常還會安裝 Jsonnet 的套件管理工具 jsonnet-bundler 用於安裝套件,例如快速建立各種 Grafana 資源的 Grafonnet。以建立一個包含 Text Panel 的 Grafana Dashboard 為例,可以使用 Grafonnet 的 dashboard 與 panel.text:
// dashboard.libsonnet
local g = import 'github.com/grafana/grafonnet/gen/grafonnet-latest/main.libsonnet';
local dashboard_name = "Jsonnet Dashboard";
local text_content = "# Hello, Jsonnet!";
g.dashboard.new(dashboard_name)
+ g.dashboard.withUid('jsonnet-dashboard')
+ g.dashboard.withDescription('Demo dashboard as code with jsonnet')
+ g.dashboard.withPanels([
g.panel.text.new("Text Panel")
+ g.panel.text.options.withMode('markdown')
+ g.panel.text.options.withContent(text_content)
+ g.panel.text.panelOptions.withGridPos(h=8, w=24, x=0, y=0)
])
編寫完後,先使用 jb install github.com/grafana/grafonnet/gen/grafonnet-latest@main
下載 Grafonnet,然後透過 jsonnet -J vendor dashboard.libsonnet
指定要匯入的套件位置與檔案,即可將內容編譯成 JSON。
使用 Jsonnet 編譯出 Dashboard JSON
生成後匯入的 Dashboard
與前面提到的 IaC 工具不同,Jsonnet 只負責生成 JSON,並不會直接執行 Dashboard 匯入。產生的 Dashboard JSON 需要再搭配其他方式匯入,例如使用 Grafana HTTP API、Terraform 的 grafana_dashboard 或是即將介紹的 Grizzly。
Grizzly 是 Grafana Labs 開發的 IaC 工具,使用 YAML 格式或 JSON 來描述 Grafana 資源。透過 grr
CLI 工具,可以將 Dashboard 等資源推送至 Grafana,例如 Dashboard 可以描述成如下的 YAML 檔:
apiVersion: grizzly.grafana.com/v1alpha1
kind: Dashboard
metadata:
folder: general
name: jsonnet-dashboard
spec:
description: Demo dashboard as code with jsonnet
panels:
- datasource:
type: datasource
uid: -- Mixed --
gridPos:
h: 8
w: 24
x: 0
y: 0
id: 1
options:
content: '#Hello, Jsonnet!'
mode: markdown
pluginVersion: v11.1.0
title: Text Panel
type: text
schemaVersion: 39
time:
from: now-6h
to: now
timezone: utc
title: Jsonnet Dashboard
uid: jsonnet-dashboard
Grizzly 提供了多種方式可以和 Grafana 互動:
grr pull resources_dir
下載 Grafana 中資源的 IaC 文件到 resources_dir
目錄下,而 grr push resources_dir
則是可以將 resources_dir
目錄中的資源同步到 Grafana 中。grr watch watched_dir resource.jsonnet
。以前面使用 Jsonnet 產生 Dashboard JSON 為例,我們可以透過 grr push
的方式將 Dashboard 同步到 Grafana 中,或是用 grr watch
即時編譯與同步。
使用 grr push
將 Dashboard 同步至 Grafana 中
使用 grr watch
監視檔案異動,並即時編譯與同步至 Grafana 中
前面介紹 Plugins 時提到的 Grafana Resources Exporter 也支援匯出 Grizzly 格式的資源 IaC 文件,但需要注意的是,Resources Exporter 的 Config 中認證資訊必須使用 Service Account Token,不能使用 Basic Auth(如 admin:admin
這種方式),否則在生成時會出現認證錯誤訊息。
使用 Resources Exporter 匯出 Grizzly 格式的 Resource
如果要使用 Grizzly 匯出的話,Grafana Authentication 必須使用 Service Account Token。
範例程式碼:https://github.com/blueswen/grafana-zero-to-hero/tree/main/07-management/04-jsonnet
此 Lab 會建立
grr
指令啟動所有服務
docker-compose up -d
編譯 Jsonnet 撰寫的 Dasboard
安裝 Jsonnet 與 jsonnet-bundler
進入 jsonnet
目錄,執行以下指令安裝 grafonnet 並編譯 Dashboard 生成 JSON 檔案
jb install github.com/grafana/grafonnet-lib@main
mkdir output
jsonnet -J vendor dashboard.libsonnet > output/dashboard.json
登入 Grafana 匯入生成的 Dashboard
admin/admi
進入 Grizzly Container 操作 grr
指令
push:推送編譯後生成的 Dashboard 到 Grafana 中
grr config create-context destination
grr config set grafana.url http://grafana:3000
grr config set grafana.user admin
grr config set grafana.token admin
grr config set targets Dashboard
grr push output/
watch:監視 jsonnet
目錄下檔案是否有異動,發生異動時重新編譯 dashboard.libsonnet
後同步至 Grafana 中,可以嘗試編輯 dashboard.libsonnet
確認效果
grr watch ./ dashboard.libsonnet
關閉所有服務
docker-compose down
Lab
範例程式碼:https://github.com/blueswen/grafana-zero-to-hero/tree/main/07-management/03-jsonnet
好像該改成
https://github.com/blueswen/grafana-zero-to-hero/tree/main/07-management/04-jsonnet
感謝雷N大大抓漏